<template>
  <div>拼接图片</div>
  <el-row :type="flex" :align="center">
    <div>
      <el-upload :before-upload="onUpload1" :multiple="true">
        <el-button>上传图</el-button>
      </el-upload>
    </div>
    <div style="margin:0 10px;">
      <el-radio-group v-model="type">
        <el-radio :value="1">纵向</el-radio>
        <el-radio :value="2">横向</el-radio>
      </el-radio-group>
    </div>
    <div>
      <el-button @click="contactFile">拼接</el-button>
    </div>
  </el-row>
  <div>
    <el-row type="flex">
      <div class="fileContainer">
        <div class="file1" v-for="(item, index) in files" :data-index="index">
          <div>图{{ index + 1 }} {{ item.imgData.width }} : {{ item.imgData.height }}</div>
          <div>
            <img :src="item.src" alt="" style="max-width:100px" />
          </div>
        </div>
      </div>
      <div class="diff" v-if="concat.src">
        <div>
          <img :src="concat.src" alt="" />
        </div>
        <el-button @click="download(concat.src)">下载</el-button>
      </div>
    </el-row>
  </div>
</template>
<script>
import '@/libs/jquery-ui-1.14.1.custom-draggable-sortable/jquery-ui.js'
import { markRaw } from 'vue'
import { exportImage } from './dataURLSaveFile.js'
export default {
  data() {
    return {
      file1: {},
      file2: {},
      files: [],
      concat: {},
      type: 1
    }
  },
  methods: {
    download(dataURL) {
      exportImage(dataURL, 'contact.png')
    },
    createCanvas(width, height) {
      var canvas = document.createElement('canvas')
      canvas.width = width
      canvas.height = height
      return canvas
    },
    contactFile() {
      let { type, files } = this
      let newImg = {}
      files = $('.fileContainer')
        .find('.file1')
        .toArray()
        .map(function(elem) {
          let index = $(elem).data('index')
          return files[index]
        })
      if (files.length > 0) {
        if (type == 1) {
          let cw = Math.max.apply(
            null,
            files.map((res) => res.imgData.width)
          )
          let ch = files.reduce((memo, res) => {
            return memo + res.imgData.height
          }, 0)
          var canvas = this.createCanvas(cw, ch)
          var ctx = canvas.getContext('2d')
          let top = 0
          files.map((res) => {
            ctx.drawImage(res.img, 0, top)
            top = top + res.imgData.height
          })
          this.concat.src = canvas.toDataURL()
        }
        if (type == 2) {
          let ch = Math.max.apply(
            null,
            files.map((res) => res.imgData.height)
          )
          let cw = files.reduce((memo, res) => {
            return memo + res.imgData.width
          }, 0)
          var canvas = this.createCanvas(cw, ch)
          var ctx = canvas.getContext('2d')
          let left = 0
          files.map((res) => {
            ctx.drawImage(res.img, left, 0)
            left = left + res.imgData.width
          })
          this.concat.src = canvas.toDataURL()
        }
      } else {
        alert('请先上传图片')
      }
    },
    onUpload1(file) {
      this.upload(file).then((res) => {
        this.files.push(markRaw(res))

        this.$nextTick((res) => {
          $('.fileContainer').sortable({
            forcePlaceholderSize: true
          })
        })
      })
      return false
    },
    upload(file) {
      return new Promise((resolve) => {
        let fr = new FileReader()
        fr.onload = (e) => {
          var img = new Image()
          img.src = e.target.result
          img.onload = () => {
            var canvas = this.createCanvas(img.width, img.height)
            var ctx = canvas.getContext('2d')
            ctx.drawImage(img, 0, 0)
            let imgData = ctx.getImageData(0, 0, img.width, img.height)
            resolve({
              img,
              imgData,
              src: e.target.result
            })
          }
        }
        fr.readAsDataURL(file)
      })
    }
  }
}
</script>
<style type="text/css" lang="scss">
.fileContainer {
  .file1 {
    display: inline-block;
    vertical-align: top;
  }
}
</style>
